import React, { useCallback, useContext, useEffect } from 'react';
import PropTypes from 'prop-types';
import FormContext from './context';
/**
  @name 表单项
  @description 用于表单项的转换
* */
function Item(props) {
  const { children, name, rules, normalize, label } = props;
  const { values={}, setValue, pushRequireArr } = useContext(FormContext);

  // 保存必填校验字段
  useEffect(()=>{
    if (rules.length >0){
      pushRequireArr({name,rules,label});
    }
  },[name, label, pushRequireArr]);

  const onChange =useCallback((value)=>{
    setValue(name, normalize(value));
  },[setValue,name]);

  if (typeof children === "function"){
    return children({value:values[name],[props.valuePropEventName]:onChange, name});
  }

  return (
    <>
      {
        React.cloneElement(children,{
          name,// todo 并不知道，不传name会有这么大的灾难，闻所未闻，导致 props 都紊乱了
          [props.valuePropName]:values[name],
          [props.valuePropEventName]:onChange,
        })
      }
    </>
  )
}
Item.defaultProps = {
  rules:[],
  valuePropName:'value',
  valuePropEventName:'onChange',
  normalize:(e)=>e,
}

Item.propTypes = {
  /**
  * @检验数组
  * @rules：[{type:'require'},{type:'number'},{type:'email'}]
  * @type 可以为  require，number，email，phone
  * */
  rules:PropTypes.arrayOf(PropTypes.shape({
    type: PropTypes.oneOf(['require', 'number', 'email']),
  })),
  /**
  * @字段名
  * */
  name:PropTypes.string,
  /**
  * @子节点的值的属性，
  * 如 Switch 的是 'checked'
  * */
  valuePropName:PropTypes.string,
  /**
  * @事件触发名称
  * */
  valuePropEventName:PropTypes.string,
  /**
  * @组件获取值后进行转换，再放入 Form 中
  * */
  normalize:PropTypes.any,
  /**
  * @在必填校验的时候，用于显示 Toast
  * */
  label: PropTypes.string,
}
export default Item;
